"""
分析全功能测试结果到xlsx文件
"""
import tkinter
import tkinter.filedialog
import tkinter.messagebox
from openpyxl import Workbook
from openpyxl.utils import get_column_letter
from openpyxl.styles import Alignment
import json
import os


def set_column_width(ws):
    k = get_column_letter(1)
    ws.column_dimensions[k].width = 30

    k = get_column_letter(2)
    ws.column_dimensions[k].width = 60

    k = get_column_letter(3)
    ws.column_dimensions[k].width = 40


def insert_item_name(ws, row_start_pos: int, row_end_pos: int, lines: list):
    cell_name = ws.cell(row_start_pos, 1)
    value_list = lines[-2].split("  ")
    cell_name.value = value_list[0]
    cell_name.alignment = Alignment(horizontal='left', vertical='center')
    ws.merge_cells(range_string=f'A{row_start_pos}:A{row_end_pos}')


def insert_record(ws, line: str, row_pos: int, name: str = None):
    line = line.strip(".\n")
    value_list = line.split(":")
    if len(value_list) == 1:
        value_list = line.split("：")
    if len(value_list) > 0:
        cell_name = ws.cell(row_pos, 2)
        if name is not None:  # 如果指定的名称
            cell_name.value = name
        else:
            cell_name.value = value_list[0]
    if len(value_list) > 1:
        cell_value = ws.cell(row_pos, 3)
        cell_value.value = value_list[1].strip("合格").strip("秒").strip("秒 合格")


# 2. 电能表时钟管理
def wite_2(ws, term_id: str, row_pos: int, log_path: str) -> int:
    # 打开log文件
    log_file = open(log_path + r"/" + term_id + "-2.log", "r", encoding="GB2312")
    # 读取文件中数据
    lines = log_file.readlines()  # 读取文件的全部行，封装到列表中
    # 关闭log文件
    log_file.close()
    # 设置表单列宽度
    set_column_width(ws)
    # 插入需要的记录数
    start_row_pos = row_pos

    insert_record(ws, lines[-24], row_pos, "RS-485通道645协议广播时差(秒)")
    row_pos += 1
    insert_record(ws, lines[-21], row_pos, "RS-485通道698协议广播时差(秒)")
    row_pos += 1
    insert_record(ws, lines[-18], row_pos, "本地通信单元645协议广播时差(秒)")
    row_pos += 1
    insert_record(ws, lines[-15], row_pos, "本地通信单元698协议广播时差(秒)")
    row_pos += 1

    cell_name = ws.cell(row_pos, 2)
    cell_name.value = "远程校时80次，共成功次数(次)"
    cell_value = ws.cell(row_pos, 3)
    line = lines[-13].strip("\n")
    value = line[8:10]
    cell_value.value = value
    row_pos += 1

    cell_name = ws.cell(row_pos, 2)
    cell_name.value = "远程校时80次，总用时(秒)"
    cell_value = ws.cell(row_pos, 3)
    line = lines[-13].strip("\n")
    value = line[-4:-1]
    cell_value.value = value
    row_pos += 1

    cell_name = ws.cell(row_pos, 2)
    cell_name.value = "80只电能表时钟超差，成功上报数(只)"
    cell_value = ws.cell(row_pos, 3)
    line = lines[-11].strip("\n")
    value = line[8:10]
    cell_value.value = value
    row_pos += 1

    cell_name = ws.cell(row_pos, 2)
    cell_name.value = "80只电能表时钟超差，上报总用时(秒)"
    cell_value = ws.cell(row_pos, 3)
    line = lines[-12].strip("\n")
    value = line[-4:-1]
    cell_value.value = value

    # 插入测试项名称
    insert_item_name(ws, start_row_pos, row_pos, lines)
    row_pos += 1
    return row_pos


# 3. 停电事件上报
def wite_3(ws, term_id: str, row_pos: int, log_path: str) -> int:
    # 打开log文件
    log_file = open(log_path + r"/" + term_id + "-3.log", "r", encoding="GB2312")
    # 读取文件中数据
    lines = log_file.readlines()  # 读取文件的全部行，封装到列表中
    # 关闭log文件
    log_file.close()
    # 设置表单列宽度
    set_column_width(ws)
    # 插入需要的记录数
    start_row_pos = row_pos
    insert_record(ws, lines[-13], row_pos, "100只电能表停电，成功上报数(只)")
    row_pos += 1
    insert_record(ws, lines[-12], row_pos, "100只电能表停电，上报总用时(秒)")
    # 插入测试项名称
    insert_item_name(ws, start_row_pos, row_pos, lines)
    row_pos += 1
    return row_pos


# 4. 并发处理能力
def wite_4(ws, term_id: str, row_pos: int, log_path: str) -> int:
    # 打开log文件
    log_file = open(log_path + r"/" + term_id + "-4.log", "r", encoding="GB2312")
    # 读取文件中数据
    lines = log_file.readlines()  # 读取文件的全部行，封装到列表中
    # 关闭log文件
    log_file.close()
    # 设置表单列宽度
    set_column_width(ws)
    # 插入需要的记录数
    start_row_pos = row_pos

    insert_record(ws, lines[-23], row_pos, "并发设置终端1000个档案,成功数量(个)")  # 并发下表档案成功数
    row_pos += 1
    insert_record(ws, lines[-21], row_pos, "并发设置档案总用时(秒)")  # 并发下表档案响应总时长
    row_pos += 1
    insert_record(ws, lines[-18], row_pos, "并发读取终端1000个档案,成功数量(个)")  # 并发读取档案成功数
    row_pos += 1
    insert_record(ws, lines[-16], row_pos, "并发读取档案总用时(秒)")  # 并发读取档案响应总时长
    row_pos += 1
    insert_record(ws, lines[-13], row_pos, "并发抄读终端1000个数据,成功数量(个)")  # 并发抄读实时数据成功数
    row_pos += 1
    insert_record(ws, lines[-11], row_pos, "并发抄读数据总用时(秒)")  # 并发抄读实时数据响应总时长

    # 插入测试项名称
    insert_item_name(ws, start_row_pos, row_pos, lines)
    row_pos += 1
    return row_pos


# 5. 远程费控
def wite_5(ws, term_id: str, row_pos: int, log_path: str) -> int:
    # 打开log文件
    log_file = open(log_path + r"/" + term_id + "-5.log", "r", encoding="GB2312")
    # 读取文件中数据
    lines = log_file.readlines()  # 读取文件的全部行，封装到列表中
    # 关闭log文件
    log_file.close()
    # 设置表单列宽度
    set_column_width(ws)
    # 插入需要的记录数
    start_row_pos = row_pos

    cell_name = ws.cell(row_pos, 2)
    cell_name.value = "645 费控30次,共成功次数(次)"
    cell_value = ws.cell(row_pos, 3)
    line = lines[-15].strip("\n")
    value = line[17:19]
    cell_value.value = value
    row_pos += 1

    cell_name = ws.cell(row_pos, 2)
    cell_name.value = "645 费控总用时(ms)"
    cell_value = ws.cell(row_pos, 3)
    line = lines[-15].strip("\n")
    value = line[-5:]
    cell_value.value = value
    row_pos += 1

    cell_name = ws.cell(row_pos, 2)
    cell_name.value = "698 费控30次,共成功次数(次)"
    cell_value = ws.cell(row_pos, 3)
    line = lines[-16].strip("\n")
    value = line[17:19]
    cell_value.value = value
    row_pos += 1

    cell_name = ws.cell(row_pos, 2)
    cell_name.value = "698 费控总用时(ms)"
    cell_value = ws.cell(row_pos, 3)
    line = lines[-16].strip("\n")
    value = line[-5:]
    cell_value.value = value
    row_pos += 1

    cell_name = ws.cell(row_pos, 2)
    cell_name.value = "累计1200只电能表,采集成功数(只)"
    cell_value = ws.cell(row_pos, 3)
    line = lines[-8].strip("\n")
    value = line[-4:]
    cell_value.value = value

    # 插入测试项名称
    insert_item_name(ws, start_row_pos, row_pos, lines)
    row_pos += 1
    return row_pos


# 6. 补抄策略
def wite_6(ws, term_id: str, row_pos: int, log_path: str) -> int:
    # 打开log文件
    log_file = open(log_path + r"/" + term_id + "-6.log", "r", encoding="GB2312")
    # 读取文件中数据
    lines = log_file.readlines()  # 读取文件的全部行，封装到列表中
    # 关闭log文件
    log_file.close()
    # 设置表单列宽度
    set_column_width(ws)
    # 插入需要的记录数
    start_row_pos = row_pos

    insert_record(ws, lines[-10], row_pos, "累计60只儒补抄的电能表,补抄成功数(只)")  # 成功数
    row_pos += 1
    insert_record(ws, lines[-7], row_pos, "累计60只需补抄的电能表,补抄总用时(秒)")  # 合计时间
    row_pos += 1

    line1 = lines[-18].strip("\n")
    num1 = line1[2:5]
    time1 = line1[-3:]
    line2 = lines[-16].strip("\n")
    num2 = line2[2:5]
    time2 = line2[-3:]

    cell_name = ws.cell(row_pos, 2)
    cell_name.value = "累计540只正常电能表,采集成功数(只)"
    cell_value = ws.cell(row_pos, 3)
    cell_value.value = int(num1) + int(num2)
    cell_value.alignment = Alignment(horizontal='left', vertical='center')
    row_pos += 1

    cell_name = ws.cell(row_pos, 2)
    cell_name.value = "累计540只正常电能表,采集总用时(秒)"
    cell_value = ws.cell(row_pos, 3)
    cell_value.value = int(time1) + int(time2)
    cell_value.alignment = Alignment(horizontal='left', vertical='center')

    # 插入测试项名称
    insert_item_name(ws, start_row_pos, row_pos, lines)
    row_pos += 1
    return row_pos


# 7. 采集压力测试
def wite_7(ws, term_id: str, row_pos: int, log_path: str) -> int:
    # 打开log文件
    log_file = open(log_path + r"/" + term_id + "-7.log", "r", encoding="GB2312")
    # 读取文件中数据
    lines = log_file.readlines()  # 读取文件的全部行，封装到列表中
    # 关闭log文件
    log_file.close()
    # 设置表单列宽度
    set_column_width(ws)
    # 插入需要的记录数
    start_row_pos = row_pos
    insert_record(ws, lines[-19], row_pos, "累计45分钟,采集到实时数据的电能表数(只)，总3000")  # 实时总成功数量
    row_pos += 1
    insert_record(ws, lines[-17], row_pos, "累计45分钟,采集到历史数据的电能表数(只)，总3000")  # 历史日总成功数量
    row_pos += 1
    insert_record(ws, lines[-30], row_pos, "累计45分钟,采集到实时数据的数据项数(个)，总48000")  # 实时总成功数据项数量
    row_pos += 1
    insert_record(ws, lines[-28], row_pos, "累计45分钟,采集到历史数据的数据项数(个)，总21000")  # 历史日总成功数据项数量
    # 插入测试项名称
    insert_item_name(ws, start_row_pos, row_pos, lines)
    row_pos += 1
    return row_pos


# 9. 分钟采集
def wite_9(ws, term_id: str, row_pos: int, log_path: str) -> int:
    # 打开log文件
    log_file = open(log_path + r"/" + term_id + "-9.log", "r", encoding="GB2312")
    # 读取文件中数据
    lines = log_file.readlines()  # 读取文件的全部行，封装到列表中
    # 关闭log文件
    log_file.close()
    # 设置表单列宽度
    set_column_width(ws)
    # 插入需要的记录数
    start_row_pos = row_pos

    insert_record(ws, lines[-17], row_pos, "20 只表的1分钟数据共60分钟,采集到表数(只)，总1200")  # 1分钟数据采集成功率
    row_pos += 1
    insert_record(ws, lines[-16], row_pos, "20 只表的1分钟数据共60分钟,采集成功数据数(个)，总6000")  # 1分钟数据数据项采集成功率
    row_pos += 1
    insert_record(ws, lines[-14], row_pos, "300 只表的15分钟数据共60分钟,采集到表数(只)，总1200")  # 15分钟数据采集成功率
    row_pos += 1
    insert_record(ws, lines[-13], row_pos, "300 只表的15分钟数据共60分钟,采集成功数据数(个)，总7200")  # 15分钟数据数据项采集成功率
    row_pos += 1
    insert_record(ws, lines[-11], row_pos, "320 只表的日数据,采集到表数(只)，总320")  # 日数据采集成功率
    row_pos += 1
    insert_record(ws, lines[-10], row_pos, "320 只表的日数据,采集成功数据数(个)，总640")  # 日数据数据项采集成功率
    row_pos += 1
    insert_record(ws, lines[-8], row_pos, "320 只表的月数据,采集到表数(只)，总320")  # 月数据采集成功率
    row_pos += 1
    insert_record(ws, lines[-7], row_pos, "320 只表的月数据,采集成功数据数(个)，总640")  # 月数据数据项采集成功率

    # 插入测试项名称
    insert_item_name(ws, start_row_pos, row_pos, lines)
    row_pos += 1
    return row_pos


def read_config() -> dict:
    config_file_io = open(config_file_path, "r", encoding="UTF-8")
    content: str = config_file_io.read()  # 全部数据
    config_file_io.close()
    config_dict = json.loads(content)  # 基础数据字典
    return config_dict


def save_config():
    config_file_io = open(config_file_path, "w", encoding="UTF-8")
    json_str = json.dumps(app_config_dict)
    config_file_io.write(json_str)
    config_file_io.close()


def calculate():
    try:
        log_path = entry_log_path.get()
        if not os.path.exists(log_path):
            var_process.set(f"{log_path} 日志路径不存在，请重新输入！")
            return
        app_config_dict["log_path"] = log_path

        term_id = entry_term_id.get()
        if len(term_id) == 0:
            var_process.set(f"终端编号为空，请重新输入！")
            return
        app_config_dict["term_id"] = term_id

        var_process.set("正在分析中...")
        work_book = Workbook()  # 创建新的xlsx Workbook
        work_sheet = work_book.create_sheet(term_id, 0)  # 创建sheet
        # 统计所有测试项结果
        xlsx_row_pos = 1
        for func in [wite_2, wite_3, wite_4, wite_5, wite_6, wite_7, wite_9]:
            xlsx_row_pos = func(work_sheet, term_id, xlsx_row_pos, log_path)
            xlsx_row_pos += 1

        output = log_path + "/" + term_id + ".xlsx"
        work_book.save(output)  # 保存统计结果xlsx
        var_process.set(f"分析完成！output:{output}")
        save_config()
    except Exception as error:
        var_process.set(f"{error}")


def open_log_path():
    # 获取文件夹路径
    value = tkinter.filedialog.askdirectory()
    if len(value) != 0:
        entry_log_path['textvariable'] = tkinter.StringVar(entry_log_path, value)


if __name__ == '__main__':
    window = tkinter.Tk()

    sw = window.winfo_screenwidth()  # 屏幕的宽度
    sh = window.winfo_screenheight()  # 屏幕的高度

    ww = 600  # 窗口的宽度
    wh = 150  # 窗口的高度

    x = (sw - ww) / 2
    y = (sh - wh) / 2

    window.title('TestDcuFFT22Assist v1.0.1')
    window.geometry("%dx%d+%d+%d" % (ww, wh, x, y))
    window.configure(background='white')

    config_file_path = os.getcwd() + "/config.json"

    app_config_dict_default = {"log_path": "C:/logs", "term_id": "SGCM2017005"}
    try:
        app_config_dict = read_config()
        app_log_path = app_config_dict["log_path"]
        app_term_id = app_config_dict["term_id"]
    except Exception as error:
        tkinter.messagebox.showerror('错误', f'配置文件加载失败，使用默认值！{error}')
        app_config_dict = app_config_dict_default
        app_log_path = app_config_dict["log_path"]
        app_term_id = app_config_dict["term_id"]

    text_log_path = tkinter.Label(window, bd=4, fg='black', bg='white', text='日志路径：')
    text_log_path.place(x=10, y=10)

    button_open = tkinter.Button(window, width=12, height=3, command=lambda: open_log_path(), text='打开')
    button_open.place(x=500, y=10)

    entry_log_path = tkinter.Entry(window, width=65, bg='#CCCCCC')
    entry_log_path.insert(0, app_log_path)
    entry_log_path.place(x=80, y=13)
    entry_log_path['state'] = 'disabled'  # normal, disabled, readonly

    text_term_id = tkinter.Label(window, bd=4, fg='black', bg='white', text='终端编号：')
    text_term_id.place(x=10, y=50)

    entry_term_id = tkinter.Entry(window, width=65, bg='#CCCCCC')
    entry_term_id.insert(0, app_term_id)
    entry_term_id.place(x=80, y=53)

    button_calculate = tkinter.Button(window, width=12, height=3, command=lambda: calculate(),
                                      text='开始分析')
    button_calculate.place(x=500, y=90)

    var_process = tkinter.StringVar(value="空闲中")
    label_process = tkinter.Label(window, bd=4, fg='red', bg='white', textvariable=var_process)
    label_process.place(x=10, y=95)

    window.mainloop()
